$(()=> {
  let $width = $('#width'),
      $height = $('#height'),
      $btnCal = $('#calc'),
      $perimeter = $('#perimeter'),
      $widthvalidate = $('#width-validate'),
      $heightvalidate = $('#height-validate'),
      $area = $('#area');

// 字符级校验
  $width.keypress((e) => {
    validate2(e);
  });

  $height.keypress((e) => {
    validate2(e);
  });


// 字段级校验
  $width.focusout(() => {
    if(!validate($width, $widthvalidate)){
      $width.select();
    }
  });
  $height.focusout(()=> {
    if(!validate($height, $heightvalidate)){
      $height.select();
    }
  });

// 表单级校验
  $btnCal.click(()=> {
    let w = Number($width.val()),
        h = Number($height.val());
    if(validate($width, $widthvalidate) && validate($height, $heightvalidate)){
      let p = (w + h) * 2,
          a = w * h;
      
      $perimeter.val(roundFractional(p,3));
      $area.val(roundFractional(a,3));
    }
  });
});

//字符级校验方法
function validate2(e){
  let key = e.key,
      val = e.target.value,
      pos = e.target.selectionStart;
  if(/[abcdf-zABCDF-Z`~!@#$%^&*()=_+[\]{}|;:'",<>/?\\]/.test(key))
    e.preventDefault();

  if(key === 'e' || key === 'E'){
    if(pos === 0 ||  val.indexOf('e') !== -1 || val.indexOf('E') !== -1 || val.slice(-1) === '.'){
      e.preventDefault();
      return;     
    }
    if(pos === 1 && val.substring(0, 1) === '-'){
      e.preventDefault();
      return;
    }
  }
    
  if(key === '.' && (pos === 0 || /\.|e|E/.test(val))){
    e.preventDefault();
    return;
  }
  
  if(key === '-' && (!/e|E/.test(val) || (val.slice(-1) !== 'e' && val.slice(-1) !== 'E'))){
    e.preventDefault();
    return;
  }   
}

// 字段级校验方法
function validate(input, output) {
  // is empty  
  if(input.val() === '') {
    output.html('该字段不能为空');
    return false;
  } else {
    output.html('');
  }
  
  // is number
  let val = Number(input.val());
  if(isNaN(val)){
    output.html('该字段是数值');
    return false;
  } else {
    output.html('');
  }

  // is +   
  if(val < 0){
    output.html('该字段不能小于0');
    return false;
  } else {
    output.html('');
  }

  return true;
}

// 浮点摄入误差
function roundFractional(x, n) {
  return Math.round(x * Math.pow(10, n)) / Math.pow(10, n);
}
